/*
 * @Author: 肖思汗 
 * @Date: 2025-06-30 19:27:22 
 * @Last Modified by: xiehangyun
 * @Last Modified time: 2025-07-29 16:30:22
 */

import { Divider } from "@nutui/nutui-react-taro";
import { ScrollView, ScrollViewProps } from "@tarojs/components";
import { isUndefined, throttle } from "lodash";
import { ReactNode, useEffect, useRef } from "react";
import { childreContolsContext } from "./MyScrollViewContext";
import MyScrollViewItem from "./MyScrollViewItem";

interface MyScrollViewProps extends ScrollViewProps {
    // 这里定义你的属性
    onScrollBottom?: (e: any) => void;
}

// 我的滚动组件
export default function MyScrollView(props: MyScrollViewProps) {

    // 子元素控制数组
    const childreContols = useRef<Array<any>>([]);
    childreContols.current = [];
    // 虚拟列表容器ref
    const scrollRef = useRef<HTMLDivElement>(null);

    const scrollTop = useRef<number>(0);
    const scrollHeight = useRef<number>(0);
    const clientHeight = useRef<number>(0);

    const { onScrollBottom, onScroll, className, children = [], ...otherProps } = props;

    useEffect(() => {
        (async () => {
            await new Promise(resolve => requestAnimationFrame(resolve));
            await new Promise(resolve => requestAnimationFrame(resolve));
            await new Promise(resolve => requestAnimationFrame(resolve));
            await new Promise(resolve => setTimeout(resolve, 100));
            if (scrollRef.current) {
                const rect = await scrollRef.current.getBoundingClientRect();
                clientHeight.current = rect.height;
                scrollHeight.current = rect.height;
                // scrollHeight.current = scrollRef.current.scrollHeight;

                let top = 0;
                childreContols.current.forEach((item, index) => {
                    if (top + item.height > scrollTop.current && top < scrollTop.current + clientHeight.current) {
                        item.isVisible(true);
                    } else {
                        item.isVisible(false);
                    }
                    top += item.height;
                });
            }
        })();
    }, []);

    // 节流
    const scroll = throttle(async (e: any) => {
        onScroll && onScroll(e);
        if (scrollRef.current) {
            const rect = await scrollRef.current.getBoundingClientRect();
            scrollTop.current = e.target.scrollTop;
            scrollHeight.current = e.target.scrollHeight;
            clientHeight.current = rect.height;

            let top = 0;
            childreContols.current.forEach((item, index) => {
                if (top + item.height > scrollTop.current && top < scrollTop.current + clientHeight.current) {
                    item.isVisible(true);
                } else {
                    item.isVisible(false);
                }
                top += item.height;
            });

            if (scrollHeight.current - clientHeight.current - scrollTop.current < 200) {
                onScrollBottom && onScrollBottom(e);
            }
        }
    }, 30);

    const childrenMap = (children: ReactNode): Array<ReactNode> => {
        if (Array.isArray(children)) {
            return children;
        } else if (!isUndefined(children)) {
            return [children];
        }
        return [];
    }

    return (
        <ScrollView
            {...otherProps}
            scrollY
            bounces={false}
            showScrollbar={false}
            type="list"
            ref={scrollRef}
            className={className}
            onScroll={scroll}
        >
            {
                <childreContolsContext.Provider
                    value={childreContols.current}
                >
                    {
                        childrenMap(children).map((child: any, index) => {
                            const contol = {
                                height: 0,
                                isVisible: (show: boolean) => { }
                            }
                            childreContols.current.push(contol);
                            return <MyScrollViewItem key={index} index={index} >{child}</MyScrollViewItem>
                        })
                    }
                </childreContolsContext.Provider>
            }

            <Divider
                style={{
                    borderStyle: 'solid',
                    width: '50%',
                    margin: '0rpx auto',
                    padding: '30rpx 0',
                }}
            >
                到底了
            </Divider>

        </ScrollView>
    );

}